package com.punai.prodatalibrary.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.multi.ListValueMap;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punai.common.bos.KVBO;
import com.punai.common.constant.HttpStatus;
import com.punai.common.core.domain.entity.SysUser;
import com.punai.common.core.page.TableDataInfo;
import com.punai.common.utils.StringUtils;
import com.punai.prodatalibrary.constants.ProjectLibConstants;
import com.punai.prodatalibrary.domain.LibProject;
import com.punai.prodatalibrary.domain.LibProjectInfo;
import com.punai.prodatalibrary.domain.SearchInfo;
import com.punai.prodatalibrary.domain.bo.GlobalProInfoBo;
import com.punai.prodatalibrary.domain.bo.ProUserBo;
import com.punai.prodatalibrary.domain.vo.SetProUserListVo;
import com.punai.prodatalibrary.mapper.LibProjectInfoMapper;
import com.punai.prodatalibrary.mapper.LibProjectMapper;
import com.punai.prodatalibrary.service.ILibProjectInfoService;
import com.punai.system.bo.ProjectAuthBo;
import com.punai.system.mapper.SysUserMapper;
import com.punai.system.service.PermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 项目基本信息Service业务层处理
 *
 * @author tj
 * @date 2023-03-31
 */
@Service
public class LibProjectInfoServiceImpl extends ServiceImpl<LibProjectInfoMapper,LibProjectInfo> implements ILibProjectInfoService
{
    @Autowired
    private LibProjectInfoMapper libProjectInfoMapper;
    @Autowired
    private LibProjectMapper libProjectMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private PermissionService permissionService;

    /**
     * 查询项目基本信息
     *
     * @param id 项目基本信息主键
     * @return 项目基本信息
     */
    @Override
    public LibProjectInfo selectLibProjectInfoById(String id)
    {
        return libProjectInfoMapper.selectLibProjectInfoById(id);
    }

    /**
     * 查询项目基本信息列表
     *
     * @param libProjectInfo 项目基本信息
     * @return 项目基本信息
     */
    @Override
    public List<LibProjectInfo> selectLibProjectInfoList(LibProjectInfo libProjectInfo)
    {
        return libProjectInfoMapper.selectLibProjectInfoList(libProjectInfo);
    }

    /**
     * 新增项目基本信息
     *
     * @param libProjectInfo 项目基本信息
     * @return 结果
     */
    @Override
    public int insertLibProjectInfo(LibProjectInfo libProjectInfo)
    {
            return libProjectInfoMapper.insert(libProjectInfo);
    }

    /**
     * 修改项目基本信息
     *
     * @param libProjectInfo 项目基本信息
     * @return 结果
     */
    @Override
    public int updateLibProjectInfo(LibProjectInfo libProjectInfo)
    {
        return libProjectInfoMapper.updateById(libProjectInfo);
    }

    /**
     * 批量删除项目基本信息
     *
     * @param ids 需要删除的项目基本信息主键
     * @return 结果
     */
    @Override
    public int deleteLibProjectInfoByIds(String[] ids)
    {
        return libProjectInfoMapper.deleteLibProjectInfoByIds(ids);
    }

    /**
     * 删除项目基本信息信息
     *
     * @param id 项目基本信息主键
     * @return 结果
     */
    @Override
    public int deleteLibProjectInfoById(String id)
    {
        return libProjectInfoMapper.deleteLibProjectInfoById(id);
    }

    /**
     * 查询所有数据
     * @return
     */
    @Override
    public List<GlobalProInfoBo> selectInfoList(GlobalProInfoBo bo) {
        if (StringUtils.isNotNull(bo.getType()) && bo.getType().equals("全部")) bo.setType(null);
        ProjectAuthBo authorityBo = permissionService.getAuthorityBo();
        bo.setAuthDeptIds(authorityBo.getAuthDeptIds());
        bo.setAuthUserName(authorityBo.getAuthUserName());
        List<GlobalProInfoBo> infoBoList = libProjectInfoMapper.selectInfoList(bo);
        List<String> ids = infoBoList.stream().filter(v -> v.getId() != null).map(GlobalProInfoBo::getId).collect(Collectors.toList());
        List<GlobalProInfoBo> resultList = new ArrayList<>();
        if (CollUtil.isNotEmpty(infoBoList)) {
            ListValueMap<String, GlobalProInfoBo> allLevelMap = new ListValueMap<>();
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                if ((StringUtils.equals(globalProInfoBo.getPid(), "0") || StringUtils.equals(globalProInfoBo.getPid(), null)) && !StringUtils.equals(globalProInfoBo.getType(), ProjectLibConstants.PRO_TYPE.F.getCode()))
                    continue;
                if (!ids.contains(globalProInfoBo.getPid())) globalProInfoBo.setPid("P");
                allLevelMap.putValue(globalProInfoBo.getPid(), globalProInfoBo);
            }
            List<GlobalProInfoBo> list = allLevelMap.get("P");
            if (list!=null){
                for (GlobalProInfoBo globalProInfoBo : list) {
                    resultList.add(globalProInfoBo);
                    String id = globalProInfoBo.getId();
                    setChildren(id, allLevelMap,globalProInfoBo);
                }
            }
        }
        return resultList;
    }

    @Override
    public TableDataInfo selectInfoListSize(GlobalProInfoBo bo) {
        if (StringUtils.isNotNull(bo.getType()) && bo.getType().equals("全部")) bo.setType(null);
        ProjectAuthBo authorityBo = permissionService.getAuthorityBo();
        bo.setAuthDeptIds(authorityBo.getAuthDeptIds());
        bo.setAuthUserName(authorityBo.getAuthUserName());
        List<GlobalProInfoBo> infoBoList = libProjectInfoMapper.selectInfoList(bo);
        List<String> ids = infoBoList.stream().filter(v -> v.getId() != null).map(GlobalProInfoBo::getId).collect(Collectors.toList());
        List<GlobalProInfoBo> resultList = new ArrayList<>();
        if (CollUtil.isNotEmpty(infoBoList)) {
            ListValueMap<String, GlobalProInfoBo> allLevelMap = new ListValueMap<>();
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                if ((StringUtils.equals(globalProInfoBo.getPid(), "0") || StringUtils.equals(globalProInfoBo.getPid(), null)) && !StringUtils.equals(globalProInfoBo.getType(), ProjectLibConstants.PRO_TYPE.F.getCode()))
                    continue;
                if (!ids.contains(globalProInfoBo.getPid())) globalProInfoBo.setPid("P");
                allLevelMap.putValue(globalProInfoBo.getPid(), globalProInfoBo);
            }
            List<GlobalProInfoBo> list = allLevelMap.get("P");
            if (list!=null){
                for (GlobalProInfoBo globalProInfoBo : list) {
                    resultList.add(globalProInfoBo);
                    String id = globalProInfoBo.getId();
                    setChildren(id, allLevelMap,globalProInfoBo);
                }
            }
        }
        Integer total = libProjectInfoMapper.selectInfoListTotal(bo);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(resultList);
        rspData.setTotal(total);
        return rspData;
    }

    @Override
    public Integer selectInfoListTotal(GlobalProInfoBo bo) {
        return libProjectInfoMapper.selectInfoListTotal(bo);
    }


    @Override
    public List<GlobalProInfoBo> selectInfoListNoPerm(GlobalProInfoBo bo) {
        if (StringUtils.isNotNull(bo.getType()) && bo.getType().equals("全部")) {
            bo.setType(null);
        }
        List<GlobalProInfoBo> infoBoList = libProjectInfoMapper.selectInfoList(bo);
        List<String> ids = infoBoList.stream().filter(v -> v.getId() != null).map(GlobalProInfoBo::getId).collect(Collectors.toList());
        List<GlobalProInfoBo> resultList = new ArrayList<>();
        if (CollUtil.isNotEmpty(infoBoList)) {
            ListValueMap<String, GlobalProInfoBo> allLevelMap = new ListValueMap<>();
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                if ((StringUtils.equals(globalProInfoBo.getPid(), "0") || StringUtils.equals(globalProInfoBo.getPid(), null)) && !StringUtils.equals(globalProInfoBo.getType(), ProjectLibConstants.PRO_TYPE.F.getCode()))
                    continue;
                if (!ids.contains(globalProInfoBo.getPid())) globalProInfoBo.setPid("P");
                allLevelMap.putValue(globalProInfoBo.getPid(), globalProInfoBo);
            }
            List<GlobalProInfoBo> list = allLevelMap.get("P");
            if (list!=null){
                for (GlobalProInfoBo globalProInfoBo : list) {
                    resultList.add(globalProInfoBo);
                    String id = globalProInfoBo.getId();
                    setChildren(id, allLevelMap,globalProInfoBo);
                }
            }
        }
        return resultList;
    }

    private void setChildren(String pid, ListValueMap<String, GlobalProInfoBo> allLevelMap,GlobalProInfoBo bo) {
        List<GlobalProInfoBo> infoBoList = allLevelMap.get(pid);
        if (CollUtil.isNotEmpty(infoBoList)) {
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                String id = globalProInfoBo.getId();
                setChildren(id, allLevelMap,globalProInfoBo);
            }
            bo.setChildren(infoBoList);
        }
    }

    @Override
    public List<LibProjectInfo> selectProjectList(GlobalProInfoBo bo) {
        if (StringUtils.isNotNull(bo.getType()) && bo.getType().equals("全部")) bo.setType(null);
        List<GlobalProInfoBo> infoBoList = libProjectInfoMapper.selectInfoList(bo);
        List<String> ids = infoBoList.stream().filter(v -> v.getId() != null).map(GlobalProInfoBo::getId).collect(Collectors.toList());
        List<LibProjectInfo> resultList = new ArrayList<>();
        if (CollUtil.isNotEmpty(infoBoList)) {
            ListValueMap<String, GlobalProInfoBo> allLevelMap = new ListValueMap<>();
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                if ((StringUtils.equals(globalProInfoBo.getPid(), "0") || StringUtils.equals(globalProInfoBo.getPid(), null)) && !StringUtils.equals(globalProInfoBo.getType(), ProjectLibConstants.PRO_TYPE.F.getCode()))
                    continue;
                if (!ids.contains(globalProInfoBo.getPid())) globalProInfoBo.setPid("P");
                allLevelMap.putValue(globalProInfoBo.getPid(), globalProInfoBo);
            }
            List<GlobalProInfoBo> list = allLevelMap.get("P");
            if (list!=null){
                for (GlobalProInfoBo globalProInfoBo : list) {
                    LibProjectInfo convet = LibProjectInfo.convet(globalProInfoBo);
                    resultList.add(convet);
                    String id = globalProInfoBo.getId();
                    setChildren2(id, allLevelMap, resultList,globalProInfoBo);
                }
            }
        }
        return resultList;
    }

    private void setChildren2(String pid, ListValueMap<String, GlobalProInfoBo> allLevelMap, List<LibProjectInfo> resultList,GlobalProInfoBo bo) {
        List<GlobalProInfoBo> infoBoList = allLevelMap.get(pid);
        if (CollUtil.isNotEmpty(infoBoList)) {
            for (GlobalProInfoBo globalProInfoBo : infoBoList) {
                String id = globalProInfoBo.getId();
                setChildren2(id, allLevelMap, resultList,globalProInfoBo);
                LibProjectInfo convet = LibProjectInfo.convet(globalProInfoBo);
                resultList.add(convet);
            }
            bo.setChildren(infoBoList);
        }
    }

    /**
     * 查询所有公司
     * @return
     */
    @Override
    public List<String> groupByDeptOfProject() {

        return libProjectInfoMapper.groupByDeptOfProject();
    }

    /**
     * 查询所有项目类型
     * @return
     */
    @Override
    public List<String> groupByProjectState() {
        return libProjectInfoMapper.groupByProjectState();
    }

    @Override
    public List<KVBO> getAllAddress() {
        List<LibProjectInfo> libProjectInfos = libProjectInfoMapper.selectList(
                Wrappers.<LibProjectInfo>lambdaQuery()
                        .select(LibProjectInfo::getProjectAddress)
        );
        Set<String> addressList = libProjectInfos.stream().map(LibProjectInfo::getProjectAddress).collect(Collectors.toSet());
        List<KVBO> result = new ArrayList<>();
        for (String s : addressList) {
            result.add(new KVBO(s,s));
        }
        return result;
    }

    @Override
    public List<SearchInfo> searchJson() {
        List<SearchInfo> list = new ArrayList<>();
        List<SearchInfo.Cascader> cascaderList = new ArrayList<>();
        List<String> depts = groupByDeptOfProject();
        for (String dept : depts) {
            SearchInfo.Cascader cascader = new SearchInfo.Cascader();
            cascader.setLabel(dept);
            cascader.setValue(dept);
            cascaderList.add(cascader);

        }
        list.add(new SearchInfo("input","测试-项目编码","projectCode","--请输入项目编码--"));
        list.add(new SearchInfo("input","测试-项目名称","projectName","--请输入项目名称--"));
        return list;
    }

    @Override
    public ProUserBo getProUserList(String proId) {
        LibProject libProject = libProjectMapper.selectById(proId);
        String aboutUserList = libProject.getAboutUserList();
        List<String> usernameList = JSON.parseArray(aboutUserList,String.class);

        ProUserBo result = new ProUserBo();
        List<String> userNames = result.getUserNames();
        List<String> userNickNames = result.getUserNickNames();

        if (CollUtil.isNotEmpty(usernameList)) {
            List<SysUser> sysUsers = sysUserMapper.selectList(
                    Wrappers.<SysUser>lambdaQuery()
                            .in(SysUser::getUserName, usernameList)
            );
            for (SysUser sysUser : sysUsers) {
                userNames.add(sysUser.getUserName());
                userNickNames.add(sysUser.getNickName());
            }
        }
        return result;
    }

    @Override
    @Transactional
    public void saveProUserList(SetProUserListVo vo) {
        String proId = vo.getProId();
        List<String> userNames = vo.getUserNames();
        String userNamesJson = JSON.toJSONString(userNames);
        libProjectMapper.update(null,
                Wrappers.<LibProject>lambdaUpdate()
                        .set(LibProject::getAboutUserList,userNamesJson)
                        .eq(LibProject::getId,proId)
        );
    }
}
